<template lang="html">
  <div class="project-run">
    <div class="wrapper">
      <div class="run-left">
        <i class="icon"></i>
      </div>
      <div class="run-right">
        <h2 class="title">运行新的任务</h2>
        <h4 class="desc">简单配置一下，运行一个任务吧</h4>
        <div class="recommend">
          <div class="configure">
            <h3 class="name">推荐配置</h3>
            <span class="custom" @click="setCustom" v-show="!selectCustom">自定义配置</span>
          </div>
          <div class="items">
            <div class="item">
              <span class="name">镜像</span>
              <el-select class="value_" v-model="image">
                 <el-option
                   v-for="(item, index) in imageArr"
                   :key="index"
                   :label="item.name"
                   :value="item.path">
                 </el-option>
               </el-select>
            </div>
            <div class="item">
              <span class="name">GPU类型</span>
              <el-select class="value_" v-model="GPUType" @change="GPUTypeChange">
                 <el-option
                   v-for="item in GPUTypeArr"
                   :key="item.value"
                   :value="item.value">
                 </el-option>
               </el-select>
            </div>
            <div class="item" v-show="!selectCustom">
              <span class="name">GPU 个数</span>
              <el-select class="value_" v-model="GPUNum">
                 <el-option
                   v-for="(item, index) in GPUNumArr"
                   :key="index"
                   :label="item.value"
                   :value="item.value">
                 </el-option>
               </el-select>
            </div>
            <div class="item" v-show="selectCustom">
              <span class="name">任务失败重启次数</span>
              <el-select class="value_" v-model="retryCount">
                 <el-option
                   v-for="(item, index) in retryCountArr"
                   :key="index"
                   :label="item.value"
                   :value="item.value">
                 </el-option>
               </el-select>
            </div>
          </div>
          <div class="equipment">
            <span class="name">配备: </span>
            <span class="info" v-show="GPUType">{{equipment}}</span>
            <!-- 2核CPU、16G内存、64M共享内存 -->
          </div>
        </div>

        <el-form label-position="top" class="form" :model="onlytaskForm" :rules="onlyrulesForm" ref="onlytaskForm" @submit.native.prevent>
          <el-form-item prop="command">
            <div class="command-start" v-show="!selectCustom">
              <h4 class="name">启动命令</h4>
              <el-input class="command" type="textarea" :rows="3" v-model="onlytaskForm.command" autocomplete="off" placeholder=" 请输入启动命令"></el-input>
            </div>
          </el-form-item>
        </el-form>

        <div class="custom-parameters" v-show="selectCustom">
          <el-form label-position="top" class="form" :model="taskForm" :rules="rulesForm" ref="taskForm" @submit.native.prevent>
            <div class="custom-task-head">
              <div class="custom-task-head-wrapper">
                <ul class="custom-task-lists">
                  <!-- <li class="task-list active">Task1</li> -->
                  <li class="task-list" v-for="(item, index) in taskList" :key="index" :class="{'active': curTaskArrId === index, 'nochecked': item.noChecked === true}"  @click="chooseTask(index)">
                    <span class="task-list-name">{{item.taskName}}</span>
                    <i class="el-icon-close task-list-del" @click.stop="delTask(index)"></i>
                  </li>
                  <li class="custom-task-add">
                    <div class="custom-task-add-btn" @click="addTask"> + 添加任务</div>
                  </li>
                </ul>
              </div>
            </div>
            <div class="custom-task-body">
              <ul class="custom-task-param">
                <li class="task-param-list">
                  <el-form-item prop="name">
                    <div class="title required">子任务名称</div>
                    <el-input class="input" v-model="taskForm.taskName" @change="taskInputChange('name', false, true)" autocomplete="off"></el-input>
                  </el-form-item>
                </li>
                <li class="task-param-list">
                  <el-form-item prop="taskNumber">
                    <div class="title required">子任务个数</div>
                    <el-input class="input" v-model="taskForm.taskNumber" @change="taskInputChange('taskNumber', false, true, 1)" autocomplete="off" placeholder="大于0的数值"></el-input>
                  </el-form-item>
                </li>
                <li class="task-param-list">
                  <el-form-item prop="gpuNumber">
                    <div class="title">GPU 个数</div>
                    <el-select class="input" v-model="taskForm.gpuNumber" @change="taskInputChange('gpuNumber', false, false, 0)">
                       <el-option
                         v-for="item in GPUNumArr"
                         :key="item.value"
                         :value="item.value">
                       </el-option>
                     </el-select>
                  </el-form-item>
                </li>
                <li class="task-param-list">
                  <el-form-item prop="minSucceededTaskCount">
                    <div class="title">最少成功次数</div>
                    <el-input class="input" v-model="taskForm.minSucceededTaskCount" autocomplete="off" @change="taskInputChange('minSucceededTaskCount', false, true, 1)" placeholder="大于0或者为空"></el-input>
                  </el-form-item>
                </li>
                <li class="task-param-list">
                  <el-form-item prop="minFailedTaskCount">
                    <div class="title">最少失败次数</div>
                    <el-input :controls="false" class="input" v-model="taskForm.minFailedTaskCount" @change="taskInputChange('minFailedTaskCount', false, true, 1)" autocomplete="off" placeholder="大于0或者为空"></el-input>
                  </el-form-item>
                </li>
              </ul>
              <div class="custom-task-command">
                <el-form-item prop="command">
                  <div class="name required">启动命令</div>
                  <el-input class="command-task" type="textarea" :rows="3" v-model="taskForm.command" @change="taskInputChange('command', false, true)" autocomplete="off" placeholder=" 请输入启动命令"></el-input>
                </el-form-item>
              </div>
            </div>
          </el-form>
        </div>
        <!-- <div class="outputs-box">
          <h4 class="title">引用Outputs</h4>
          <div class="outputs-project">
            <el-select v-model="value" placeholder="请选择">
              <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                class="outputs-project-option"
                :value="item.value">
              </el-option>
            </el-select>
          </div>
          <div class="outputs-task">
            <el-select v-model="valueTask" placeholder="请选择">
              <el-option
                v-for="item in optionsTask"
                :key="item.value"
                :label="item.label"
                class="outputs-project-option"
                :value="item.value">
              </el-option>
            </el-select>
          </div>
        </div> -->
        <!-- <div class="super-parameter">
          <div class="super-parameter-top">
            <h4>
              设置超参数 >
            </h4>
            <div class="super-parameter-add" @click="superParameterAddFun()">
              <i class="super-parameter-add-ico"></i>
              增加一个参数
            </div>
          </div>
          <div class="super-parameter-con">
            <ul class="super-parameter-wrap" v-if="parameterWrap.length>0">
              <li class="super-parameter-item" v-for="(item, index) in parameterWrap" :key="index">
                <el-input v-model="item.parameterName" placeholder="请输入内容"></el-input>
                <el-input v-model="item.parameterNum" placeholder="请输入内容"></el-input>
                <div class="super-parameter-dele" @click="deletSuper(index)"><img src="@/common/image/icon/dele-super-item.png" alt=""></div>
              </li>
            </ul>
          </div>
        </div> -->
        <div class="cost-payby" v-if="payByList.length > 0">
          <h4 class="title">支付方式：</h4>
          <el-radio-group class="payby-group" v-model="payBy">
            <el-radio class="payby-group-item" v-for="(item, index) in payByList" :key="index" :label="item.teamId" @change="selectPowerBy($event, item)">以{{item.teamName}}账号支付<span v-if="selectedTeamId == item.teamId" class="payby-group-item-remaining">剩余&nbsp;{{Number(item.power).toFixed(1)}}&nbsp;算力</span></el-radio>
          </el-radio-group>
        </div>

        <div class="cost-estimate">
          <div class="info">
            <span class="infotitle">费用预估: </span>按当前配置，任务运行需要耗费
            <span class="num">{{estimateCost}} 算力/小时</span>
          </div>
          <div class="cost-rule">
            <el-popover
              placement="top"
              trigger="hover"
              width="500">
              <div class="rule-detail-wrapper">
                <ul class="rule-detail">
                  <li class="items" v-for="(item, index) in ruleArr" :key="index">
                    <div class="info">
                      <span class="name">{{item.gpu_type}}</span>
                      {{item.cpu_num}}核CPU，{{item.memory_num}}G内存
                    </div>
                    <span class="hourly">{{item.cal_power}}算力/小时</span>
                  </li>
                </ul>
              </div>
              <span class="rule" slot="reference">查看计费规则</span>
            </el-popover>
            <a class="recharge" @click="toOrder">
              <i class="icon">￥</i>
              算力充值
            </a>
          </div>
        </div>
        <div class="save-task">
          <el-button class="save-run-btn" type="primary" @click="saveTaskRun" :disabled="btnState" :class="{'disable': btnState}">保存并运行任务</el-button>
          <el-button class="save-btn" @click="saveTask" :disabled="btnState" :class="{'disable': btnState}">仅保存</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapMutations, mapGetters } from 'vuex'
import { imagesGetList } from '../../api/image'
import { getCalculationPowerConfList, getUserCalculationPower, addTeamTaskRelation } from '../../api/order'
import { createTask, projectEdit2 } from '../../api/project'
import { getTeamListWithPower } from '../../api/team'
import { randomNumber, isNewId } from '../../common/js/getRandCharacter'
import qs from 'qs'

export default {
  data () {
    let validatetaskNumber = (rule, value, callback) => {
      if (value && value.length > 0 && Number(value) === 0) {
        callback(new Error('子任务个数须大于0'))
      } else if (Number(value) > 20) {
        callback(new Error('子任务个数不能大于20'))
      } else {
        if (this.taskForm.minSucceededTaskCount && this.taskForm.minSucceededTaskCount.length > 0) this.$refs.taskForm.validateField('minSucceededTaskCount')
        if (this.taskForm.minFailedTaskCount && this.taskForm.minFailedTaskCount.length > 0) this.$refs.taskForm.validateField('minFailedTaskCount')
        callback()
      }
    }
    let validateTaskCountDiffSucc = (rule, value, callback) => {
      if (value && value.length > 0 && Number(value) === 0) {
        callback(new Error('最少成功次数须大于0或者为空'))
      } else if (Number(value) > Number(this.taskForm.taskNumber)) {
        callback(new Error('最大值不能超过当前子任务个数'))
      } else {
        callback()
      }
    }
    let validateTaskCountDiffFail = (rule, value, callback) => {
      if (value && value.length > 0 && Number(value) === 0) {
        callback(new Error('最少失败次数须大于0或者为空'))
      } else if (Number(value) > Number(this.taskForm.taskNumber)) {
        callback(new Error('最大值不能超过当前子任务个数'))
      } else {
        callback()
      }
    }
    return {
      parameterArr: [],
      parameterBrn: true,
      parameterWrap: [],
      valueTask: '',
      value: '',
      // 剩余算力
      residualCalculation: 0,
      // 当前用户剩余算力
      surplusCalculationPower: 0,
      // 预计算力
      estimateCost: 0,
      // 镜像
      image: '',
      // 镜像集合
      imageArr: [],
      // gpu类型
      GPUType: 'gtx1080ti',
      // gpu类型集合
      GPUTypeArr: [],
      // 纯CPU计算数据
      GPUTypeSpe: {},
      // 计费规则集合
      ruleArr: [],
      // gpu数量
      GPUNum: 1,
      // gpu数量集合
      GPUNumArr: [],
      // 重启次数
      retryCount: 0,
      // 重启次数集合
      selectedTeamId: '',
      retryCountArr: [],
      // 选择自定义配置
      selectCustom: false,
      // 启动命令
      command: '',
      // 配备
      equipment: '',
      // 自定义配置 参数 form
      taskForm: {
        taskName: 'Task1',
        minSucceededTaskCount: '',
        minFailedTaskCount: '',
        cpuNumber: '',
        taskNumber: '',
        memoryMB: '',
        gpuNumber: 1,
        shmMB: '',
        command: ''
      },
      // 当前选择任务
      curTaskArrId: 0,
      // 是否可添加子任务
      taskStatus: false,
      // Task数据
      taskList: [
        {
          taskName: 'Task1',
          minSucceededTaskCount: '',
          minFailedTaskCount: '',
          cpuNumber: '',
          taskNumber: '',
          memoryMB: '',
          gpuNumber: 1,
          shmMB: '',
          command: ''
        }
      ],
      // 表单校验规则
      rulesForm: {
        taskName: [
          {
            required: true,
            message: '请输入子任务名称',
            trigger: 'blur'
          }, {
            max: 20,
            message: '名称长度不能超过20个字符'
          }, {
            pattern: /^[a-zA-Z][a-zA-Z0-9_-]*$/,
            message: '名称由字母或数字组成,并且以字母开头'
          }
        ],
        taskNumber: [
          {
            required: true,
            message: '请输入子任务个数',
            trigger: 'blur'
            // validator: validatetaskNumber
          }, {
            pattern: /^[0-9]+$/,
            message: '请输入数字'
          }, {
            validator: validatetaskNumber
          }
        ],
        minSucceededTaskCount: [
          {
            required: false,
            trigger: 'blur',
            validator: validateTaskCountDiffSucc
          }, {
            pattern: /^[0-9]+$/,
            message: '请输入数字'
          }
        ],
        minFailedTaskCount: [
          {
            required: false,
            trigger: 'blur',
            validator: validateTaskCountDiffFail
          }, {
            pattern: /^[0-9]+$/,
            message: '请输入数字'
          }
        ],
        command: [
          {
            required: true,
            message: '请输入启动命令',
            trigger: 'blur'
          }, {
            max: 500,
            message: '命令行内容不能超过500字符'
          }
        ]
      },
      onlytaskForm: {
        command: ''
      },
      onlyrulesForm: {
        command: [
          {
            required: true,
            message: '请输入启动命令',
            trigger: 'blur'
          }, {
            max: 500,
            message: '命令行内容不能超过500字符'
          }
        ]
      },
      // 支付方式
      payBy: -99,
      // 选择支付列表
      payByList: [],
      btnState: false
    }
  },
  methods: {
    superParameterAddFun () {
      var newObjct = {}
      newObjct.parameterName = ''
      newObjct.parameterNum = ''
      this.parameterWrap.push(newObjct)
    },
    // 设置 自定义配置模式
    setCustom () {
      this.selectCustom = true
      this.GPUNum = 0
      // this.taskForm.command = this.onlytaskForm.command.split(' --')[0]
      this.taskForm.command = this.onlytaskForm.command
      // this.taskList[0].command = this.onlytaskForm.command.split(' --')[0]
      this.taskList[0].command = this.onlytaskForm.command
      this.onlytaskForm.command = '请输入启动命令'
      this.parameterWrap = []
    },
    // 创建子任务 并运行
    saveTaskRun () {
      if (!this.image) {
        this.$message({ message: '请选择镜像', showClose: true, type: 'warning' })
        return false
      }
      if (!this.selectCustom) {
        this.$refs.onlytaskForm.validate((valid) => {
          if (valid) this._createTaskRun()
        })
      } else {
        this._createTaskRun()
      }
    },
    // 创建 子任务
    saveTask () {
      if (!this.image) {
        this.$message({ message: '请选择镜像', showClose: true, type: 'warning' })
        return false
      }
      if (!this.selectCustom) {
        this.$refs.onlytaskForm.validate((valid) => {
          if (valid) this._createTask()
        })
      } else {
        this._createTask()
      }
    },
    // GPU类型改变
    GPUTypeChange (value) {
      this.costEstimate()
    },
    // 添加任务
    addTask () {
      this.testingTask()
      if (!this.taskStatus) return false
      let newTaskItem = {
        taskName: `Task${this.taskList.length + 1}`,
        minSucceededTaskCount: '',
        minFailedTaskCount: '',
        taskNumber: '',
        gpuNumber: 1,
        command: ''
      }
      this.taskList.push(newTaskItem)
      this.parameterWrap = []
      this.curTaskArrId = this.taskList.length - 1
      this.chooseTask(this.curTaskArrId, false)
      this.costEstimate()
    },
    // 删除任务
    delTask (index) {
      if (this.taskList.length > 1) {
        this.taskList.splice(index, 1)
        if ((parseInt(index)) === parseInt(this.curTaskArrId)) {
          this.curTaskArrId = 0
          this.chooseTask(0, false)
        } else {
          this.curTaskArrId = this.curTaskArrId - 1
        }
      }
    },
    deletSuper (indexs) {
      var curTaskArrIdnum = this.curTaskArrId
      this.taskList[curTaskArrIdnum].valNameAAA.splice(indexs, 1)
    },
    // 选择任务
    chooseTask (index, status = true) {
      if (status) {
        this.testingTask()
        if (!this.taskStatus) return false
      }
      this.curTaskArrId = index
      this.taskForm.taskName = this.taskList[index].taskName
      this.taskForm.minSucceededTaskCount = this.taskList[index].minSucceededTaskCount
      this.taskForm.minFailedTaskCount = this.taskList[index].minFailedTaskCount
      this.taskForm.taskNumber = this.taskList[index].taskNumber
      this.taskForm.gpuNumber = this.taskList[index].gpuNumber
      this.taskForm.command = this.taskList[index].command
      // this.taskForm.command = this.taskList[index].command.split(' --')[0]
      if (this.taskList[index].valNameAAA) {
        this.parameterWrap = this.taskList[index].valNameAAA
      } else {
        this.parameterWrap = []
      }
      // this.parameterWrap = this.taskList[index].valNameAAA
    },
    // 提交新建任务  检测表格参数是否合法
    testingTask () {
      this.$refs.taskForm.validate((valid) => {
        if (valid) {
          // 校验taskList列表
          if (this.checkEmptyTaskList()) {
            this.taskStatus = false
            return false
          } else {
            this.taskStatus = true
          }
        } else {
          this.taskStatus = false
          return false
        }
      })
    },
    // Tasklist 非空校验
    checkEmptyTaskList () {
      let checkFlag = false
      this.taskList.map((item, index) => {
        if (item.taskName === '' || item.taskNumber === '' || item.command === '') {
          // 数组更新赋值，解决vue数组直接赋值页面不能及时更新状态问题
          let tempItem = this.taskList[index]
          tempItem.noChecked = true
          this.$set(this.taskList, index, tempItem)
          checkFlag = true
        } else {
          let tempItem = this.taskList[index]
          tempItem.noChecked = false
          this.$set(this.taskList, index, tempItem)
        }
      })
      return checkFlag
    },
    // 预估算力 计算
    costEstimate () {
      if (this.selectCustom) {
        // 自定义配置
        let calPower = 0
        let cpuNum = 0
        let memoryNum = 0
        let sharedMemoryNum = 0
        this.ruleArr.forEach(item => {
          if (item.gpu_type === this.GPUType) {
            this.taskList.forEach(list => {
              let listTaskNumber = list.taskNumber || 1
              if (list.gpuNumber === 0) {
                calPower += this.GPUTypeSpe.cal_power * Number(listTaskNumber)
                cpuNum += this.GPUTypeSpe.cpu_num
                memoryNum += this.GPUTypeSpe.memory_num
                sharedMemoryNum += this.GPUTypeSpe.shared_memory_num
              } else {
                calPower += item.cal_power * Number(list.gpuNumber) * Number(listTaskNumber)
                cpuNum += item.cpu_num * Number(list.gpuNumber)
                memoryNum += item.memory_num * Number(list.gpuNumber)
                sharedMemoryNum += item.shared_memory_num * Number(list.gpuNumber)
              }
            })
          }
        })
        this.estimateCost = calPower.toFixed(2)
        this.equipment = `${cpuNum}核CPU、${memoryNum}G内存、${sharedMemoryNum}M共享内存`
      } else {
        // 非自定义配置
        if (this.GPUNum === 0) {
          this.estimateCost = (this.GPUTypeSpe.cal_power).toFixed(2)
          this.equipment = `${this.GPUTypeSpe.cpu_num}核CPU、${this.GPUTypeSpe.memory_num}G内存、${this.GPUTypeSpe.shared_memory_num}M共享内存`
        } else {
          this.ruleArr.forEach(item => {
            if (item.gpu_type === this.GPUType) {
              this.estimateCost = (item.cal_power * this.GPUNum).toFixed(2)
              this.equipment = `${item.cpu_num * this.GPUNum}核CPU、${item.memory_num * this.GPUNum}G内存、${item.shared_memory_num * this.GPUNum}M共享内存`
            }
          })
        }
      }
    },
    /*
      Task输入框输入变化
      valName: 输入值
      isNumberInput：是否数字输入框
      required：是否必填，用于根据输入值变化更新tasklist的状态
      min: 最小值
      max: 最大值
    */
    superChange (val) {
      if (val === '') {
        this.taskList[this.curTaskArrId]['valNameAAA'] = ''
      } else {
        val.forEach(v => {
          // console.log(v.parameterName !== '', v.parameterNum !== '')
          if (v.parameterName.indexOf(' ') === -1 && v.parameterNum.indexOf(' ') === -1) {
            this.taskList[this.curTaskArrId]['valNameAAA'] = val
          } else {
            v.parameterName = v.parameterName.replace(/\s+/g, '')
            v.parameterNum = v.parameterNum.replace(/\s+/g, '')
            this.taskList[this.curTaskArrId]['valNameAAA'] = val
          }
        })
      }
    },
    superfunbtn (v) {
      if (v === '' || v === undefined) {
        return ''
      } else {
        var strsuper = ''
        var arrsuper = []
        for (var i = 0; i < v.length; i++) {
          if (v[i].parameterName && v[i].parameterNum) {
            if (v[i].parameterName !== '' && v[i].parameterNum !== '') {
              strsuper = v[i].parameterName + ' ' + v[i].parameterNum
              arrsuper.push(strsuper)
            }
            //  else if (this.v[i].parameterName === '' && v[i].parameterNum !== '') {
            //   console.log('请输入参数')
            // } else if (v[i].parameterName !== '' && v[i].parameterNum === '') {
            //   console.log('请输入参数')
            // } else {
            //   console.log('有整体为空的值')
            // }
          }
        }
        var mysupersrt = arrsuper.join(' --')
        return mysupersrt
      }
    },
    taskInputChange (valName, isNumberInput, required, min, max) {
      // 判断是否为数字类型输入框，是的话替换非数字输入
      if (this.taskForm[valName] !== '' && isNumberInput) {
        this.taskForm[valName] = this.taskForm[valName].replace(/\D/g, '')
        let num = Number(this.taskForm[valName])
        num = min !== undefined && num < min ? min : num
        num = max !== undefined && num > max ? max : num
        this.taskForm[valName] = num
      }
      // 同步输入表单输入到任务数组
      this.taskList[this.curTaskArrId][valName] = this.taskForm[valName]
      if (required) {
        this.checkEmptyTaskList()
      }
      if (valName === 'taskNumber' || valName === 'gpuNumber') {
        this.costEstimate()
      }
    },
    // 打开上传数据集新窗口
    toOrder () {
      const { href } = this.$router.resolve({
        name: 'order',
        path: '/order'
      })
      window.open(href, '_blank')
    },
    selectPowerBy (label, item) {
      this.residualCalculation = item.power
      this.selectedTeamId = item.teamId
      if (this.residualCalculation) this.residualCalculation = Number(this.residualCalculation).toFixed(1)
      if (!this.residualCalculation) this.residualCalculation = 0
    },
    /*
      -----接口调用-----
    */
    // 获取GPU类型
    _getCalculationPowerConfList () {
      const query = `?number=1&token=${this.userInfo.bitaToken}`
      getCalculationPowerConfList(query).then(res => {
        if (res.code === 0) {
          res.result && res.result.forEach(item => {
            if (item.gpu_flag === 0) {
              this.GPUTypeSpe = item
              this.GPUTypeSpe.shared_memory_num = item.memory_num * 512
            } else {
              this.GPUTypeArr.push({
                value: item.gpu_type,
                gpu_type: item.gpu_type,
                cpu_num: item.cpu_num,
                memory_num: item.memory_num,
                // shared_memory_num: item.shared_memory_num
                shared_memory_num: item.memory_num * 512
              })
            }
            let item_ = item
            item_.shared_memory_num = item.memory_num * 512
            this.ruleArr.push(item_)
          })
          this.GPUTypeChange(this.GPUType)
          this.costEstimate()
          this.fillData()
        }
      })
    },
    // 获取当前用户剩余算力
    _getUserCalculationPower () {
      const query = `?number=1&token=${this.userInfo.bitaToken}`
      getUserCalculationPower(query).then(res => {
        this._getTeamListWithPower()
        if (res.code === 0) this.surplusCalculationPower = res.result.surplusCalculationPower.toFixed(1)
        this.residualCalculation = this.surplusCalculationPower
      })
    },
    // 创建子任务 运行
    _createTaskRun () {
      // 算力计算 判断
      if (Number(this.residualCalculation) < Number(this.estimateCost)) {
        this.$message({ message: '当前算力不足，请充值', showClose: true, type: 'warning' })
        return false
      }
      let data = {}
      data.projectId = this.curProject.id
      data.projectName = this.curProject.projectName
      data.jobType = 1
      data.codeNo = this.jobCodeNo
      let configObj = JSON.parse(this.curProject.config)
      configObj.apiVersion = '2.0'
      configObj.kind = this.GPUType === 'debug' ? 'debug' : 'execution'
      configObj.jobName = data.projectName + '-' + isNewId(randomNumber())
      configObj.retryCount = this.retryCount
      configObj.taskRoles = [{}]
      configObj.code = {
        projectId: this.curProject.projectName,
        mountPath: '/code',
        timeStamp: '',
        version: ''
      }
      // configObj.datasets = configObj.datasets
      configObj.model = {
        modelId: '',
        mountPath: '',
        token: ''
      }
      configObj.output = {
        'jobId': ''
      }
      if (this.selectCustom) {
        // 自定义配置
        this.testingTask()
        if (this.taskStatus) {
          configObj.taskRoles.length = 0
          this.taskList.forEach(item => {
            let taskRolesTem = {}
            taskRolesTem.taskName = item.taskName
            taskRolesTem.taskNumber = Number(item.taskNumber)
            taskRolesTem.image = this.image
            taskRolesTem.gpuType = this.GPUType
            taskRolesTem.gpuNumber = item.gpuNumber
            taskRolesTem.minSucceededTaskCount = item.minSucceededTaskCount || null
            taskRolesTem.minFailedTaskCount = item.minFailedTaskCount || null
            if (Number(taskRolesTem.gpuNumber) === 0) {
              taskRolesTem.cpuNumber = this.GPUTypeSpe.cpu_num
              taskRolesTem.memoryMB = this.GPUTypeSpe.memory_num * 1024
              taskRolesTem.shmMB = this.GPUTypeSpe.shared_memory_num
            } else {
              this.GPUTypeArr.forEach(list => {
                if (list.gpu_type === this.GPUType) {
                  taskRolesTem.cpuNumber = list.cpu_num * Number(taskRolesTem.gpuNumber)
                  taskRolesTem.memoryMB = list.memory_num * 1024 * Number(taskRolesTem.gpuNumber)
                  taskRolesTem.shmMB = list.shared_memory_num * Number(taskRolesTem.gpuNumber)
                }
              })
            }
            if (item.valNameAAA && item.valNameAAA.length > 0) {
              var supertext = this.superfunbtn(item.valNameAAA)
              taskRolesTem.command = item.command + ' --' + supertext
            } else {
              taskRolesTem.command = item.command
            }
            configObj.taskRoles.push(taskRolesTem)
          })
        } else {
          this.$message({ message: '子任务参数错误', showClose: true, type: 'warning' })
          return false
        }
      } else {
        // 非自定义配置
        configObj.taskRoles[0].taskName = 'Task1'
        configObj.taskRoles[0].taskNumber = 1
        configObj.taskRoles[0].image = this.image
        configObj.taskRoles[0].gpuType = this.GPUType
        configObj.taskRoles[0].gpuNumber = this.GPUNum
        configObj.taskRoles[0].minFailedTaskCount = null
        configObj.taskRoles[0].minSucceededTaskCount = null
        if (this.taskList[0].valNameAAA && this.taskList[0].valNameAAA.length > 0) {
          var supertext = this.superfunbtn(this.taskList[0].valNameAAA)
          configObj.taskRoles[0].command = this.onlytaskForm.command + ' --' + supertext
        } else {
          configObj.taskRoles[0].command = this.onlytaskForm.command
        }
        if (Number(configObj.taskRoles[0].gpuNumber) === 0) {
          configObj.taskRoles[0].cpuNumber = this.GPUTypeSpe.cpu_num
          configObj.taskRoles[0].memoryMB = this.GPUTypeSpe.memory_num * 1024
          configObj.taskRoles[0].shmMB = this.GPUTypeSpe.shared_memory_num
        } else {
          this.GPUTypeArr.forEach(item => {
            if (item.gpu_type === this.GPUType) {
              configObj.taskRoles[0].cpuNumber = item.cpu_num * Number(configObj.taskRoles[0].gpuNumber)
              configObj.taskRoles[0].memoryMB = item.memory_num * 1024 * Number(configObj.taskRoles[0].gpuNumber)
              configObj.taskRoles[0].shmMB = item.shared_memory_num * Number(configObj.taskRoles[0].gpuNumber)
            }
          })
        }
      }
      data.config = JSON.stringify(configObj)
      // 当 payBy为-99时 个人支付，无需发请求
      if (this.payBy !== -99) {
        this._addTeamTaskRelation(configObj.jobName, data)
      } else {
        this._createTaskRunRequest(data)
      }
    },
    // 创建任务运行请求接口
    _createTaskRunRequest (data) {
      this.btnState = true
      createTask(data).then(res => {
        this.btnState = false
        if (res.message.code === 0) {
          if (res.data) {
            let temData = this.curProject
            temData.config = res.data
            this.storeProject(temData)
          } else {
            let temData = this.curProject
            temData.config = data.config
            this.storeProject(temData)
          }
          // 创建目录
          this.$message({ message: '新建任务成功', showClose: true, type: 'success' })
          this.$nextTick(() => {
            this.$router.push({
              'path': '/project/detail/task',
              'query': {
                'projectid': this.curProject.id
              }
            })
          })
        } else if (res.message.code === 40012) {
          this.$message({ message: '运行任务的项目代码不能超过200M,请修改代码后重新运行', showClose: true, type: 'error' })
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      }).catch(() => {
        this.btnState = false
      })
    },
    // 创建子任务 仅保存
    _createTask () {
      let query = '?dataSetIds='
      let data = {}
      data.filePath = this.curProject.projectName + '/code'
      data.notes = this.curProject.notes
      data.profile = this.curProject.profile
      data.projectName = this.curProject.projectName
      data.userId = this.userInfo.userId
      data.id = this.curProject.id
      data.language = this.curProject.language
      data.algorithm = this.curProject.algorithm
      let configObj = JSON.parse(this.curProject.config)
      configObj.apiVersion = '2.0'
      configObj.kind = this.GPUType === 'debug' ? 'debug' : 'execution'
      configObj.jobName = data.projectName + '-' + isNewId(randomNumber())
      configObj.retryCount = this.retryCount
      configObj.taskRoles = [{}]
      configObj.code = {
        projectId: this.curProject.projectName,
        mountPath: '/code',
        timeStamp: '',
        version: ''
      }
      // configObj.datasets = configObj.datasets
      configObj.model = {
        modelId: '',
        mountPath: '',
        token: ''
      }
      configObj.output = {
        'jobId': ''
      }
      if (this.selectCustom) {
        // 自定义配置
        this.testingTask()
        configObj.retryCount = this.retryCount
        if (this.taskStatus) {
          configObj.taskRoles.length = 0
          this.taskList.forEach(item => {
            let taskRolesTem = {}
            taskRolesTem.taskName = item.taskName
            taskRolesTem.taskNumber = item.taskNumber
            taskRolesTem.image = this.image
            taskRolesTem.gpuType = this.GPUType
            taskRolesTem.gpuNumber = item.gpuNumber || 1
            taskRolesTem.minSucceededTaskCount = item.minSucceededTaskCount || null
            taskRolesTem.minFailedTaskCount = item.minFailedTaskCount || null
            this.GPUTypeArr.forEach(list => {
              if (list.gpu_type === this.GPUType) {
                taskRolesTem.cpuNumber = list.cpu_num
                taskRolesTem.memoryMB = list.memory_num * 1024
                taskRolesTem.shmMB = list.shared_memory_num
              }
            })
            if (item.valNameAAA && item.valNameAAA.length > 0) {
              var supertext = this.superfunbtn(item.valNameAAA)
              taskRolesTem.command = item.command + ' --' + supertext
            } else {
              taskRolesTem.command = item.command
            }
            configObj.taskRoles.push(taskRolesTem)
          })
        } else {
          this.$message({ message: '子任务参数错误', showClose: true, type: 'warning' })
          return false
        }
      } else {
        // 非自定义配置
        configObj.taskRoles[0].taskName = 'Task1'
        configObj.taskRoles[0].taskNumber = 1
        configObj.taskRoles[0].image = this.image
        configObj.taskRoles[0].gpuType = this.GPUType
        configObj.taskRoles[0].gpuNumber = this.GPUNum
        configObj.taskRoles[0].minFailedTaskCount = null
        configObj.taskRoles[0].minSucceededTaskCount = null
        if (this.taskList[0].valNameAAA && this.taskList[0].valNameAAA.length > 0) {
          var supertext = this.superfunbtn(this.taskList[0].valNameAAA)
          configObj.taskRoles[0].command = this.onlytaskForm.command + ' --' + supertext
        } else {
          configObj.taskRoles[0].command = this.onlytaskForm.command
        }
        this.GPUTypeArr.forEach(item => {
          if (item.gpu_type === this.GPUType) {
            configObj.taskRoles[0].cpuNumber = item.cpu_num
            configObj.taskRoles[0].memoryMB = item.memory_num * 1024
            configObj.taskRoles[0].shmMB = item.shared_memory_num
          }
        })
      }
      data.config = JSON.stringify(configObj)
      this.btnState = true
      projectEdit2(query, data).then(res => {
        this.btnState = false
        if (res.message.code === 0) {
          this.$message({ message: '任务保存成功', showClose: true, type: 'success' })
          if (res.data) {
            this.storeProject(res.data)
          } else {
            this.storeProject(data)
          }
          this.$nextTick(() => {
            this.$router.push({
              'path': '/project/list'
            })
          })
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      }).catch(() => {
        this.btnState = false
      })
    },
    // 设置任务随机名
    setRandomTaskName (name) {
      let sname = name
      let rdString = isNewId(randomNumber())
      let sResult = ''
      if (sname !== null && sname.trim().length > 0) {
        if (sname.lastIndexOf('_') === -1) {
          sResult = sname.concat('_' + rdString)
        } else {
          let lastNumber = sname.slice(-1) // 获取最后一位
          let check = isNewId(sname.slice(-6, -1)).slice(-1)
          if (check !== lastNumber) {
            if (lastNumber === '_') {
              sResult = sname.concat(rdString)
            } else {
              sResult = sname.concat('_' + rdString)
            }
          } else {
            let sJudge = sname.substr(0, (sname.lastIndexOf('_')))
            sResult = sJudge.concat('_' + rdString)
          }
        }
      }
      return sResult
    },
    // 获取镜像列表
    _imagesGetList () {
      const query = `?language=${this.curProject.language}&framework=${this.curProject.algorithm}`
      imagesGetList(query).then(res => {
        if (res.message.code === 0) {
          this.imageArr = [...res.data]
          this.image = this.imageArr[0].path
        }
        this._getCalculationPowerConfList()
      })
    },
    // 获取团队列表带算力
    _getTeamListWithPower () {
      getTeamListWithPower().then(res => {
        if (res.message.code === 0) {
          if (res.data && res.data.length > 0) {
            this.payByList.push({
              teamId: -99,
              teamName: '个人',
              power: this.surplusCalculationPower
            })
            this.payByList = [...this.payByList.concat(res.data)]
            this.selectedTeamId = -99
          }
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 添加团队任务关系
    _addTeamTaskRelation (taskName, taskData) {
      let data = qs.stringify({
        teamId: this.payBy,
        taskName: taskName,
        cluster: process.env.VUE_APP_CLUSTER,
        token: this.userInfo.bitaToken
      })
      addTeamTaskRelation(data).then(res => {
        if (res.code === 0) {
          this._createTaskRunRequest(taskData)
        } else {
          this.$message({ message: res.msg, showClose: true, type: 'error' })
        }
      })
    },
    // 保存任务填充参数
    fillData () {
      let curProjectGet = this.curProject
      let curProjectGetConfig = JSON.parse(curProjectGet.config)
      if (curProjectGetConfig && curProjectGetConfig.taskRoles && curProjectGetConfig.taskRoles.length > 1) {
        this.setCustom()
        this.image = curProjectGetConfig.taskRoles[0].image
        this.GPUType = curProjectGetConfig.taskRoles[0].gpuType
        this.retryCount = curProjectGetConfig.retryCount
        this.taskList = [...curProjectGetConfig.taskRoles]
        this.curTaskArrId = 0
        this.taskForm.taskName = this.taskList[0].taskName
        this.taskForm.minSucceededTaskCount = this.taskList[0].minSucceededTaskCount
        this.taskForm.minFailedTaskCount = this.taskList[0].minFailedTaskCount
        this.taskForm.taskNumber = this.taskList[0].taskNumber
        this.taskForm.gpuNumber = this.taskList[0].gpuNumber
        // this.taskForm.command = this.taskList[0].command.split(' --')[0]
        this.taskForm.command = this.taskList[0].command
      } else if (curProjectGetConfig && curProjectGetConfig.taskRoles && curProjectGetConfig.taskRoles.length === 1) {
        // this.onlytaskForm.command = curProjectGetConfig.taskRoles[0].command.split(' --')[0]
        this.onlytaskForm.command = curProjectGetConfig.taskRoles[0].command
        this.GPUType = curProjectGetConfig.taskRoles[0].gpuType
        this.GPUNum = curProjectGetConfig.taskRoles[0].gpuNumber
        this.image = curProjectGetConfig.taskRoles[0].image
        this.costEstimate()
      } else {
        if (this.GPUTypeArr.length > 0) {
          this.GPUType = this.GPUTypeArr[0].value
        }
      }
    },
    // 获取数据
    _setArrNumber (min, max) {
      let arrNew = []
      for (let i = min; i <= max; i++) {
        arrNew.push({
          value: i
        })
      }
      return arrNew
    },
    ...mapMutations({
      storeProject: 'SET_CUR_PROJECT'
    })
  },
  computed: {
    ...mapGetters([
      'userInfo',
      'curProject',
      'jobCodeNo'
    ])
  },
  mounted () {
    this._imagesGetList()
    this._getUserCalculationPower()
    this.GPUNumArr = this._setArrNumber(0, 8)
    this.retryCountArr = this._setArrNumber(0, 1000)
    // this._getTeamListWithPower()
  },
  watch: {
    GPUNum () {
      this.costEstimate()
    },
    parameterWrap: {
      handler: function (val, oldVal) {
        this.superChange(val)
      },
      deep: true
    }
  }
}
</script>

<style lang="stylus">
.project-run
  width 100%
  font-family PingFangSC-Regular
  .wrapper
    width 1162px
    margin 0 auto
    padding: 64px 0
    font-size 0
    .run-left
      display inline-block
      // width 294px
      text-align right
      vertical-align top
      .icon
        display inline-block
        width 139px
        height 82px
        background url(../../common/image/icon-project/icon-new-task.png) no-repeat center
        background-size 139px 82px
    .run-right
      display inline-block
      width 868px
      padding-left 32px
      font-size 12px
      .save-task
        .save-run-btn
          &.el-button
            width 200px
          &.el-button--primary
            background-color #2E94F9
            &.el-button--primary:hover
              background-color #36a0f6
        .el-button+.el-button
          margin-left 22px
        .save-btn
          &.el-button
            width 122px
          &.el-button--primary
            background-color #ffffff
        .disable
          background #ccc!important
          border-color #ccc!important
          color #fff!important
      .title
        height 100px
        line-height 110px
        font-size 28px
        color #2D323B
        font-family 'PingFangSC-Medium'
        font-weight 600
      .desc
        line-height 20px
        font-size 14px
        color #7F7F7F
        padding-bottom 36px
      .recommend
        width 100%
        padding 20px 22px
        background #F8F8F8
        border-radius 4px
        .configure
          display flex
          padding-bottom 20px
          .name
            flex 1
            height 20px
            line-height 20px
            font-size 14px
            color #2D323B
            font-weight 600
          .custom
            flex 0 0 100px
            height 20px
            line-height 20px
            font-size 14px
            color #2196F3
            text-align right
            font-weight 600
            cursor pointer
        .items
          display flex
          padding-bottom 14px
          .item
            flex 1
            display flex
            padding-right 18px
            .name
              // flex 0 0 70px
              height 40px
              line-height 40px
              padding-right 10px
              font-size 14px
              color #2D323B
            .value_
              flex 1
              font-size 14px
              color #2D323B
        .equipment
          height 20px
          line-height 20px
          font-size 14px
          color #8C8C8C
      .command-start
        padding-top 28px
        .name
          height 34px
          line-height 20px
          font-size 14px
          color #2D323B
          font-weight 600
      .custom-parameters
        width 100%
        margin 24px 0 12px 0
        background #f8f8f8
        border-radius 4px
        .custom-task-head
          width 836px
          // height 36px
          font-size 0
          border-bottom 1px solid #d1d1d1
          .custom-task-head-wrapper
            // height 36px
            .custom-task-lists
              display inline-block
              max-width 100%
              // height 36px
              font-size 0
              .task-list
                display inline-block
                width 118px
                height 36px
                line-height 36px
                padding 0 8px
                font-size 14px
                color #333
                cursor pointer
                vertical-align top
                font-weight 600
                &:hover
                  background #e8e8e8
                  color #2E94F9
                  color
                  .task-list-del
                    opacity 1
                .task-list-name
                  display inline-block
                  width 80%
                  height 36px
                  line-height 36px
                  overflow hidden
                  text-overflow ellipsis
                  white-space nowrap
                  vertical-align top
                .task-list-del
                  opacity 0
                  font-size 14px
                  cursor pointer
                  &:hover
                    color #f00
              .active
                background #e8e8e8
                color #2E94F9
              .nochecked
                color #f56c6c
              .custom-task-add
                display inline-block
                width 118px
                height 36px
                line-height 36px
                padding 0 12px
                font-size 14px
                color #333
                cursor pointer
                user-select none
                &:hover
                  background #e2e2e2
            // .custom-task-add
            //   display inline-block
            //   width 14%
            //   height 36px
            //   line-height 36px
            //   text-align center
            //   font-size 14px
            //   color #333
            //   cursor pointer
            //   &:hover
            //     background #c2c2c2
        .custom-task-body
          width 100%
          padding 10px 20px
          .custom-task-param
            width 100%
            font-size 0
            .task-param-list
              display inline-block
              width 30%
              margin-right 5%
              &:nth-child(3n+3)
                margin-right 0
              .title
                height 36px
                line-height 36px
                font-size 14px
                color #333
          .custom-task-command
            width 100%
            padding-bottom 12px
            .name
              height 36px
              line-height 36px
              font-size 14px
              color #333
              font-weight 600
      .cost-payby
        width 100%
        padding-top 30px
        display flex
        .title
          flex 0 0 80px
          line-height 20px
          font-size 14px
          color #2D323B
        .payby-group
          padding-left 12px
          flex 1
          .payby-group-item
            display block
            margin-left 0
            margin-bottom 17px
            .el-radio__label
              height 20px
              line-height 20px
            .el-radio__label
              padding-left 14px
              color #2D323B
            .payby-group-item-remaining
              margin-left 45px
              font-size 14px
              color #6E6E6E
              line-height 20px
          .payby-group-item:last-child
            margin-bottom 14px
      .outputs-box
        display flex
        align-items center
        padding 15px 0 13px
        .title
          font-size 14px
          height 20px
          line-height 20px
          margin-right 16px
        .outputs-project,.outputs-task
          margin-right 22px
          width 150px
          .el-input__inner
            height 20px
            line-height 20px
            border none
            color #2D323B
            font-size 14px
          .el-input__icon
            line-height 20px
      .super-parameter
        .super-parameter-con
          .super-parameter-wrap
            display flex
            flex-wrap wrap
            margin-top 14px
            margin-bottom 22px
            background #F8F9FA
            padding 20px 22px 6px
            .super-parameter-item
              width 320px
              margin-right 72px
              margin-bottom 14px
              .el-input
                width 130px
                margin-right 12px
              .el-input__inner
                height 34px
                line-height 34px
                border none
                color #2D323B
              .super-parameter-dele
                width 14px
                height 14px
                display inline-block
                cursor pointer
                img
                  width 100%
                  height 100%
        .super-parameter-top
          display flex
          align-items center
          padding-top 6px
          padding-bottom 2px
          h4
            font-size 14px
            line-height 20px
            color #2D323B
            font-family 'PingFangSC-Medium'
            font-weight 600
            margin-right 13px
          .super-parameter-add
            font-size 14px
            line-height 20px
            color #7F7F7F
            display flex
            align-items center
            cursor pointer
            .super-parameter-add-ico
              width 14px
              height 14px
              margin-top 2px
              margin-right 7px
              display inline-block
              background url(../../common/image/icon/super-parameter-add-ico.png) no-repeat center
              background-size 12px 12px
      .cost-estimate
        display flex
        padding 12px 0 40px 0
        .info
          flex 1
          height 20px
          line-height 20px
          font-size 14px
          color #6e6e6e
          .infotitle
            font-weight 600
            margin-right 5px
            color #2d323b
          .num
            color #EE6723
        .cost-rule
          flex 0 0 200px
          font-size 0
          text-align right
          .rule
            display inline-block
            height 20px
            line-height 20px
            padding-right 20px
            font-size 14px
            color #309EEC
            vertical-align top
            cursor pointer
          .recharge
            display inline-block
            height 20px
            line-height 20px
            font-size 14px
            color #309EEC
            cursor pointer
            .icon
              display inline-block
              width 14px
              height 14px
              line-height 14px
              text-align center
              font-size 12px
              color #fff
              background #309EEC
              border-radius 50%
              margin-top 2px
.rule-detail-wrapper
  padding 30px
  .rule-detail
    width 100%
    .items
      height 41px
      border-bottom 1px dashed #ddd
      display flex
      .info
        flex 1
        height 40px
        line-height 40px
        font-size 14px
        color #666
        .name
          font-size 14px
          color #333
          padding-right 10px
          font-weight 600
      .hourly
        flex 0 0 28%
        height 40px
        line-height 40px
        font-size 14px
        color #555
        text-align right
.el-select-dropdown__item.selected.outputs-project-option
  color #3DA8FD
  font-weight normal
</style>
